package com.kelvin.backend.common.util.date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Optional;

/**
 * <p>Title: LocalDateTimeUtil</p>
 * <p>Description: </p>
 *
 * @author Kelvin.Chen
 * @datetime 2020/12/11 16:30
 */
public class LocalDateTimeUtil {

    private static final Logger log = LoggerFactory.getLogger(LocalDateTimeUtil.class);

    /**
     * 获取指定时间的字符串
     *
     * @param ldt           默认是当前时间
     * @param pattern       默认是yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String getDateStr(LocalDateTime ldt, String pattern) {
        Optional.ofNullable(ldt).orElse(LocalDateTime.now());
        Optional.ofNullable(pattern).orElse(DatePattern.NORMAL_DATETIME_PATTERN);
        return ldt.format(DateTimeFormatter.ofPattern(pattern));
    }
    
    /**
     * Date 转 LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime date2LocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * LocalDateTime 转 Date
     *
     * @param ldt
     * @return
     */
    public static Date localDateTime2Date(LocalDateTime ldt) {
        return Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取毫秒
     *
     * @param ldt
     * @return
     */
    public static Long getMilliByLocalDateTime(LocalDateTime ldt) {
        Optional.ofNullable(ldt).orElse(LocalDateTime.now());
        return ldt.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 获取秒
     * 
     * @param ldt
     * @return
     */
    public static Long getSecondByLocalDateTime(LocalDateTime ldt) {
        Optional.ofNullable(ldt).orElse(LocalDateTime.now());
        return ldt.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    /**
     * 计算日期
     *
     * @param ldt
     * @param num
     * @param unit
     * @param type  Constants常量类里的PLUS或MINUS
     * @return
     */
    public static LocalDateTime calculateDate(LocalDateTime ldt, long num, ChronoUnit unit, String type) {
        if (DatePattern.PLUS.equals(type)) {
            return ldt.plus(num, unit);
        } else if (DatePattern.MINUS.equals(type)) {
            return ldt.minus(num, unit);
        } else {
            log.warn("not support the type");
            return ldt;
        }
    }

    /**
     * 计算两个日期之间的差距
     *
     * @param startLDT
     * @param endLDT
     * @param unit      如果传null，默认是天为单位
     * @return
     */
    public static long betweenLocalDateTime(LocalDateTime startLDT, LocalDateTime endLDT, ChronoUnit unit) throws Exception {
        if (null == startLDT || null == endLDT) {
            log.warn("起始时间或结束时间不能为空，startLDT -> {}，endLDT -> {}", startLDT, endLDT);
            throw new Exception("起始时间或结束时间不能为空");
        }
        Optional.ofNullable(unit).orElse(ChronoUnit.DAYS);
        return unit.between(startLDT, endLDT);
    }

}
